package vn.com.epi.web;

import java.io.File;
import java.io.IOException;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

import org.apache.log4j.PropertyConfigurator;

import vn.com.epi.buffer.LogBuffer;

/**
 * Initialize and destroy our application together with servlet context. When
 * initializing, actively check any possible mistake in configuration and throw
 * exception.
 * 
 */
@WebListener
public class Application implements ServletContextListener {

    public static final String LOG_DIR_PARAM = "log.dir";
    public static final String LOG_BUFFER_MAX_SIZE_PARAM = "log.buffer_max";
    public static final String LOG_FILENAME_PATTERN_PARAM = "log.filename_pattern";
	
	private static LogBuffer logBuffer;
	private static Exception exception;
	private static ServletContext servletContext;
	
	/**
     * Default constructor. 
     */
    public Application() {
    }

	public static void init(ServletContext servletContext) {
		try {
		    Application.servletContext = servletContext;
		    initLog4j();
			checkLogParams();
			initLogBuffer();
		} catch (Exception e) {
			exception = e;
			servletContext.log("Error while initializing application", e);
		}
	}

	private static void initLog4j() {
	    PropertyConfigurator.configure(servletContext.getRealPath(
	            "/WEB-INF/classes/log4j.properties"));
    }

    public static void destroy(ServletContext servletContext) {
		try {
			if (logBuffer != null) {
				logBuffer.flush(servletContext);
			}
		} catch (IOException e) {
		    servletContext.log("Error while closing log buffer", e);
		}
	}

	public static void initLogBuffer() {
		logBuffer = new LogBuffer(Integer.parseInt(
				servletContext.getInitParameter(LOG_BUFFER_MAX_SIZE_PARAM)));
	}

	public static void checkLogParams() throws IOException {
	    String dir = servletContext.getInitParameter(LOG_DIR_PARAM);
	    File theDir = new File(dir);
		if (!(theDir.exists() && theDir.isDirectory())) {
			if (!theDir.mkdir()) {
				throw new IOException("Cannot create log directory: " + dir);
			}
		}
		File checkFile = new File (dir, ".check");
		if (!checkFile.delete() && !checkFile.createNewFile()) {
			throw new IOException("Cannot write to log directory.");
		}
		if (servletContext.getInitParameter(LOG_FILENAME_PATTERN_PARAM) == null) {
			throw new IOException("Log filename pattern not found.");
		}
	}

    /**
     * @see ServletContextListener#contextInitialized(ServletContextEvent)
     */
    public void contextInitialized(ServletContextEvent evt) {
    	init(evt.getServletContext());
    }

	/**
     * @see ServletContextListener#contextDestroyed(ServletContextEvent)
     */
    public void contextDestroyed(ServletContextEvent evt) {
    	destroy(evt.getServletContext());
    }

    public static LogBuffer getLogBuffer() {
		return logBuffer;
	}
    
    public static Exception getException() {
		return exception;
	}
    
}
